//! # 安全审计模块
//!
//! 提供完整的安全事件记录、审计追踪和合规性支持

use rustcloud_security::prelude::*;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use uuid::Uuid;
use chrono::{DateTime, Utc};

#[cfg(feature = "audit")]
use sqlx::{Pool, Postgres, Row};

/// 安全审计器
#[derive(Clone)]
pub struct SecurityAuditor {
    config: AuditConfig,
    #[cfg(feature = "audit")]
    db_pool: Option<Arc<Pool<Postgres>>>,
    memory_store: Arc<RwLock<Vec<SecurityEvent>>>,
}

/// 审计配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditConfig {
    /// 是否启用审计
    pub enabled: bool,
    /// 审计级别
    pub level: AuditLevel,
    /// 存储后端
    pub storage: AuditStorage,
    /// 数据保留天数
    pub retention_days: u32,
    /// 是否记录敏感数据
    pub include_sensitive_data: bool,
    /// 批量写入大小
    pub batch_size: usize,
    /// 刷新间隔（秒）
    pub flush_interval: u64,
}

/// 审计级别
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuditLevel {
    /// 基础审计
    Basic,
    /// 详细审计
    Detailed,
    /// 完整审计
    Full,
}

/// 审计存储
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuditStorage {
    /// 内存存储（用于测试）
    Memory,
    /// 数据库存储
    Database,
    /// 文件存储
    File(String),
    /// 远程日志服务
    Remote(String),
}

/// 安全事件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecurityEvent {
    /// 事件ID
    pub id: String,
    /// 事件类型
    pub event_type: SecurityEventType,
    /// 事件时间
    pub timestamp: DateTime<Utc>,
    /// 用户ID
    pub user_id: Option<String>,
    /// 会话ID
    pub session_id: Option<String>,
    /// 服务名称
    pub service: String,
    /// 资源路径
    pub resource: String,
    /// 操作类型
    pub action: String,
    /// 客户端IP
    pub client_ip: Option<String>,
    /// 用户代理
    pub user_agent: Option<String>,
    /// 事件结果
    pub result: EventResult,
    /// 错误信息
    pub error_message: Option<String>,
    /// 风险级别
    pub risk_level: RiskLevel,
    /// 事件详情
    pub details: HashMap<String, serde_json::Value>,
    /// 地理位置
    pub location: Option<GeoLocation>,
}

/// 审计事件（SecurityEvent的别名，保持向后兼容）
pub type AuditEvent = SecurityEvent;

/// 安全事件类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SecurityEventType {
    /// 认证事件
    Authentication(AuthEventType),
    /// 授权事件
    Authorization(AuthzEventType),
    /// 会话事件
    Session(SessionEventType),
    /// 数据访问事件
    DataAccess(DataAccessEventType),
    /// 配置变更事件
    Configuration(ConfigEventType),
    /// 系统事件
    System(SystemEventType),
    /// 安全事件
    Security(SecurityIncidentType),
}

/// 认证事件类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuthEventType {
    /// 登录尝试
    LoginAttempt,
    /// 登录成功
    LoginSuccess,
    /// 登录失败
    LoginFailure,
    /// 登出
    Logout,
    /// 密码重置
    PasswordReset,
    /// 密码变更
    PasswordChange,
    /// 多因素认证
    MfaChallenge,
    /// 令牌刷新
    TokenRefresh,
}

/// 授权事件类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuthzEventType {
    /// 权限检查
    PermissionCheck,
    /// 访问授权
    AccessGranted,
    /// 访问拒绝
    AccessDenied,
    /// 角色分配
    RoleAssignment,
    /// 权限变更
    PermissionChange,
}

/// 会话事件类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SessionEventType {
    /// 会话创建
    SessionCreated,
    /// 会话更新
    SessionUpdated,
    /// 会话过期
    SessionExpired,
    /// 会话终止
    SessionTerminated,
}

/// 数据访问事件类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DataAccessEventType {
    /// 数据读取
    DataRead,
    /// 数据写入
    DataWrite,
    /// 数据删除
    DataDelete,
    /// 数据导出
    DataExport,
    /// 敏感数据访问
    SensitiveDataAccess,
}

/// 配置变更事件类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConfigEventType {
    /// 安全配置变更
    SecurityConfigChange,
    /// 权限配置变更
    PermissionConfigChange,
    /// 系统配置变更
    SystemConfigChange,
}

/// 系统事件类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SystemEventType {
    /// 服务启动
    ServiceStart,
    /// 服务停止
    ServiceStop,
    /// 系统错误
    SystemError,
    /// 性能警告
    PerformanceAlert,
}

/// 安全事件类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SecurityIncidentType {
    /// 暴力破解攻击
    BruteForceAttack,
    /// 可疑IP活动
    SuspiciousIpActivity,
    /// 异常访问模式
    AnomalousAccessPattern,
    /// 权限提升尝试
    PrivilegeEscalationAttempt,
    /// 数据泄露风险
    DataLeakageRisk,
}

/// 事件结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EventResult {
    /// 成功
    Success,
    /// 失败
    Failure,
    /// 错误
    Error,
    /// 警告
    Warning,
}

/// 风险级别
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RiskLevel {
    /// 低风险
    Low,
    /// 中等风险
    Medium,
    /// 高风险
    High,
    /// 严重风险
    Critical,
}

/// 地理位置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GeoLocation {
    /// 国家
    pub country: Option<String>,
    /// 城市
    pub city: Option<String>,
    /// 纬度
    pub latitude: Option<f64>,
    /// 经度
    pub longitude: Option<f64>,
}

/// 审计查询条件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditQuery {
    /// 用户ID
    pub user_id: Option<String>,
    /// 服务名称
    pub service: Option<String>,
    /// 事件类型
    pub event_type: Option<SecurityEventType>,
    /// 开始时间
    pub start_time: Option<DateTime<Utc>>,
    /// 结束时间
    pub end_time: Option<DateTime<Utc>>,
    /// 风险级别
    pub risk_level: Option<RiskLevel>,
    /// 页面大小
    pub page_size: Option<usize>,
    /// 页面偏移
    pub offset: Option<usize>,
}

/// 审计报告
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditReport {
    /// 报告ID
    pub id: String,
    /// 生成时间
    pub generated_at: DateTime<Utc>,
    /// 报告期间
    pub period: ReportPeriod,
    /// 事件统计
    pub event_statistics: EventStatistics,
    /// 用户活动统计
    pub user_activity: Vec<UserActivitySummary>,
    /// 风险事件
    pub risk_events: Vec<SecurityEvent>,
    /// 合规性检查结果
    pub compliance_check: ComplianceResult,
}

/// 报告期间
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReportPeriod {
    /// 开始时间
    pub start_time: DateTime<Utc>,
    /// 结束时间
    pub end_time: DateTime<Utc>,
}

/// 事件统计
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EventStatistics {
    /// 总事件数
    pub total_events: u64,
    /// 成功事件数
    pub successful_events: u64,
    /// 失败事件数
    pub failed_events: u64,
    /// 高风险事件数
    pub high_risk_events: u64,
    /// 事件类型分布
    pub event_type_distribution: HashMap<String, u64>,
}

/// 用户活动摘要
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserActivitySummary {
    /// 用户ID
    pub user_id: String,
    /// 登录次数
    pub login_count: u64,
    /// 最后登录时间
    pub last_login: DateTime<Utc>,
    /// 访问的服务数
    pub services_accessed: u64,
    /// 风险评分
    pub risk_score: f64,
}

/// 合规性检查结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComplianceResult {
    /// 检查时间
    pub checked_at: DateTime<Utc>,
    /// 合规性状态
    pub status: ComplianceStatus,
    /// 检查项目
    pub checks: Vec<ComplianceCheck>,
}

/// 合规性状态
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ComplianceStatus {
    /// 合规
    Compliant,
    /// 部分合规
    PartiallyCompliant,
    /// 不合规
    NonCompliant,
}

/// 合规性检查项
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComplianceCheck {
    /// 检查项名称
    pub name: String,
    /// 检查结果
    pub result: bool,
    /// 描述
    pub description: String,
    /// 建议
    pub recommendation: Option<String>,
}

impl SecurityAuditor {
    /// 创建新的安全审计器
    pub fn new(config: AuditConfig) -> Self {
        Self {
            config,
            #[cfg(feature = "audit")]
            db_pool: None,
            memory_store: Arc::new(RwLock::new(Vec::new())),
        }
    }

    /// 使用数据库池创建审计器
    #[cfg(feature = "audit")]
    pub fn with_database(config: AuditConfig, db_pool: Arc<Pool<Postgres>>) -> Self {
        Self {
            config,
            db_pool: Some(db_pool),
            memory_store: Arc::new(RwLock::new(Vec::new())),
        }
    }

    /// 记录安全事件
    pub async fn log_event(&self, event: SecurityEvent) -> SecurityResult<()> {
        if !self.config.enabled {
            return Ok(());
        }

        match &self.config.storage {
            AuditStorage::Memory => {
                let mut store = self.memory_store.write().await;
                store.push(event);
                
                // 限制内存中的事件数量
                if store.len() > 10000 {
                    store.remove(0);
                }
            },
            #[cfg(feature = "audit")]
            AuditStorage::Database => {
                if let Some(pool) = &self.db_pool {
                    self.store_event_to_db(pool, &event).await?;
                }
            },
            AuditStorage::File(path) => {
                self.store_event_to_file(path, &event).await?;
            },
            AuditStorage::Remote(_url) => {
                // TODO: 实现远程日志服务
            },
        }

        Ok(())
    }

    /// 记录认证事件
    pub async fn log_auth_event(
        &self,
        event_type: AuthEventType,
        user_id: Option<String>,
        context: &AuthContext,
        result: EventResult,
        error_message: Option<String>,
    ) -> SecurityResult<()> {
        let event = SecurityEvent {
            id: Uuid::new_v4().to_string(),
            event_type: SecurityEventType::Authentication(event_type),
            timestamp: Utc::now(),
            user_id,
            session_id: context.headers.get("session-id").cloned(),
            service: "auth-service".to_string(),
            resource: context.path.clone(),
            action: context.method.clone(),
            client_ip: context.client_ip.clone(),
            user_agent: context.headers.get("user-agent").cloned(),
            result,
            error_message,
            risk_level: self.calculate_risk_level(&context).await,
            details: HashMap::new(),
            location: None, // TODO: 实现地理位置解析
        };

        self.log_event(event).await
    }

    /// 记录授权事件
    pub async fn log_authz_event(
        &self,
        event_type: AuthzEventType,
        principal: &Principal,
        resource: &Resource,
        context: &AuthContext,
        result: EventResult,
    ) -> SecurityResult<()> {
        let event = SecurityEvent {
            id: Uuid::new_v4().to_string(),
            event_type: SecurityEventType::Authorization(event_type),
            timestamp: Utc::now(),
            user_id: Some(principal.id.clone()),
            session_id: context.headers.get("session-id").cloned(),
            service: resource.service.clone(),
            resource: resource.path.clone(),
            action: resource.action.clone(),
            client_ip: context.client_ip.clone(),
            user_agent: context.headers.get("user-agent").cloned(),
            result,
            error_message: None,
            risk_level: self.calculate_risk_level(&context).await,
            details: HashMap::new(),
            location: None,
        };

        self.log_event(event).await
    }

    /// 查询审计事件
    pub async fn query_events(&self, query: AuditQuery) -> SecurityResult<Vec<SecurityEvent>> {
        match &self.config.storage {
            AuditStorage::Memory => {
                let store = self.memory_store.read().await;
                let filtered: Vec<SecurityEvent> = store
                    .iter()
                    .filter(|event| self.matches_query(event, &query))
                    .cloned()
                    .collect();
                Ok(filtered)
            },
            #[cfg(feature = "audit")]
            AuditStorage::Database => {
                if let Some(pool) = &self.db_pool {
                    self.query_events_from_db(pool, &query).await
                } else {
                    Ok(Vec::new())
                }
            },
            _ => Ok(Vec::new()),
        }
    }

    /// 生成审计报告
    pub async fn generate_report(&self, period: ReportPeriod) -> SecurityResult<AuditReport> {
        let query = AuditQuery {
            user_id: None,
            service: None,
            event_type: None,
            start_time: Some(period.start_time),
            end_time: Some(period.end_time),
            risk_level: None,
            page_size: None,
            offset: None,
        };

        let events = self.query_events(query).await?;
        
        // 计算统计信息
        let total_events = events.len() as u64;
        let successful_events = events.iter()
            .filter(|e| matches!(e.result, EventResult::Success))
            .count() as u64;
        let failed_events = events.iter()
            .filter(|e| matches!(e.result, EventResult::Failure | EventResult::Error))
            .count() as u64;
        let high_risk_events = events.iter()
            .filter(|e| matches!(e.risk_level, RiskLevel::High | RiskLevel::Critical))
            .count() as u64;

        let event_statistics = EventStatistics {
            total_events,
            successful_events,
            failed_events,
            high_risk_events,
            event_type_distribution: HashMap::new(), // TODO: 实现事件类型分布统计
        };

        // 计算用户活动
        let user_activity = self.calculate_user_activity(&events).await;

        // 筛选风险事件
        let risk_events: Vec<SecurityEvent> = events.into_iter()
            .filter(|e| matches!(e.risk_level, RiskLevel::High | RiskLevel::Critical))
            .take(100) // 限制数量
            .collect();

        // 合规性检查
        let compliance_check = self.perform_compliance_check().await;

        Ok(AuditReport {
            id: Uuid::new_v4().to_string(),
            generated_at: Utc::now(),
            period,
            event_statistics,
            user_activity,
            risk_events,
            compliance_check,
        })
    }

    /// 计算风险级别
    async fn calculate_risk_level(&self, context: &AuthContext) -> RiskLevel {
        // 简单的风险评估逻辑
        let mut risk_score = 0;

        // 检查IP地址
        if let Some(ip) = &context.client_ip {
            if ip.starts_with("192.168.") || ip.starts_with("10.") || ip.starts_with("172.") {
                // 内网IP，风险较低
                risk_score += 0;
            } else {
                // 外网IP，风险中等
                risk_score += 1;
            }
        }

        // 根据路径判断敏感度
        if context.path.contains("/admin") || context.path.contains("/config") {
            risk_score += 2;
        }

        match risk_score {
            0..=1 => RiskLevel::Low,
            2..=3 => RiskLevel::Medium,
            4..=5 => RiskLevel::High,
            _ => RiskLevel::Critical,
        }
    }

    /// 检查查询条件是否匹配
    fn matches_query(&self, event: &SecurityEvent, query: &AuditQuery) -> bool {
        if let Some(user_id) = &query.user_id {
            if event.user_id.as_ref() != Some(user_id) {
                return false;
            }
        }

        if let Some(service) = &query.service {
            if &event.service != service {
                return false;
            }
        }

        if let Some(start_time) = query.start_time {
            if event.timestamp < start_time {
                return false;
            }
        }

        if let Some(end_time) = query.end_time {
            if event.timestamp > end_time {
                return false;
            }
        }

        true
    }

    /// 计算用户活动统计
    async fn calculate_user_activity(&self, events: &[SecurityEvent]) -> Vec<UserActivitySummary> {
        let mut user_stats: HashMap<String, UserActivitySummary> = HashMap::new();

        for event in events {
            if let Some(user_id) = &event.user_id {
                let summary = user_stats.entry(user_id.clone()).or_insert_with(|| {
                    UserActivitySummary {
                        user_id: user_id.clone(),
                        login_count: 0,
                        last_login: event.timestamp,
                        services_accessed: 0,
                        risk_score: 0.0,
                    }
                });

                // 更新统计信息
                if matches!(event.event_type, SecurityEventType::Authentication(AuthEventType::LoginSuccess)) {
                    summary.login_count += 1;
                    if event.timestamp > summary.last_login {
                        summary.last_login = event.timestamp;
                    }
                }

                // 计算风险评分
                match event.risk_level {
                    RiskLevel::Critical => summary.risk_score += 4.0,
                    RiskLevel::High => summary.risk_score += 3.0,
                    RiskLevel::Medium => summary.risk_score += 2.0,
                    RiskLevel::Low => summary.risk_score += 1.0,
                }
            }
        }

        user_stats.into_values().collect()
    }

    /// 执行合规性检查
    async fn perform_compliance_check(&self) -> ComplianceResult {
        let mut checks = Vec::new();

        // 检查是否启用审计
        checks.push(ComplianceCheck {
            name: "审计启用".to_string(),
            result: self.config.enabled,
            description: "审计功能应该启用".to_string(),
            recommendation: if !self.config.enabled {
                Some("启用审计功能".to_string())
            } else {
                None
            },
        });

        // 检查数据保留期
        checks.push(ComplianceCheck {
            name: "数据保留期".to_string(),
            result: self.config.retention_days >= 90,
            description: "审计数据应至少保留90天".to_string(),
            recommendation: if self.config.retention_days < 90 {
                Some("将数据保留期设置为至少90天".to_string())
            } else {
                None
            },
        });

        let compliant_checks = checks.iter().filter(|c| c.result).count();
        let total_checks = checks.len();

        let status = if compliant_checks == total_checks {
            ComplianceStatus::Compliant
        } else if compliant_checks > 0 {
            ComplianceStatus::PartiallyCompliant
        } else {
            ComplianceStatus::NonCompliant
        };

        ComplianceResult {
            checked_at: Utc::now(),
            status,
            checks,
        }
    }

    /// 存储事件到文件
    async fn store_event_to_file(&self, path: &str, event: &SecurityEvent) -> SecurityResult<()> {
        use tokio::fs::OpenOptions;
        use tokio::io::AsyncWriteExt;

        let json_line = serde_json::to_string(event)
            .map_err(|e| SecurityError::OperationFailed {
                operation: "serialize_event".to_string(),
                reason: e.to_string(),
            })?;

        let mut file = OpenOptions::new()
            .create(true)
            .append(true)
            .open(path)
            .await
            .map_err(|e| SecurityError::OperationFailed {
                operation: "open_audit_file".to_string(),
                reason: e.to_string(),
            })?;

        file.write_all(format!("{}\n", json_line).as_bytes())
            .await
            .map_err(|e| SecurityError::OperationFailed {
                operation: "write_audit_file".to_string(),
                reason: e.to_string(),
            })?;

        Ok(())
    }

    /// 存储事件到数据库
    #[cfg(feature = "audit")]
    async fn store_event_to_db(&self, pool: &Pool<Postgres>, event: &SecurityEvent) -> SecurityResult<()> {
        let event_type_json = serde_json::to_value(&event.event_type)
            .map_err(|e| SecurityError::OperationFailed {
                operation: "serialize_event_type".to_string(),
                reason: e.to_string(),
            })?;

        let details_json = serde_json::to_value(&event.details)
            .map_err(|e| SecurityError::OperationFailed {
                operation: "serialize_details".to_string(),
                reason: e.to_string(),
            })?;

        sqlx::query!(
            r#"
            INSERT INTO security_events (
                id, event_type, timestamp, user_id, session_id, service, 
                resource, action, client_ip, user_agent, result, 
                error_message, risk_level, details
            ) VALUES (
                $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14
            )
            "#,
            event.id,
            event_type_json,
            event.timestamp,
            event.user_id,
            event.session_id,
            event.service,
            event.resource,
            event.action,
            event.client_ip,
            event.user_agent,
            serde_json::to_string(&event.result).unwrap(),
            event.error_message,
            serde_json::to_string(&event.risk_level).unwrap(),
            details_json
        )
        .execute(pool)
        .await
        .map_err(|e| SecurityError::OperationFailed {
            operation: "insert_audit_event".to_string(),
            reason: e.to_string(),
        })?;

        Ok(())
    }

    /// 从数据库查询事件
    #[cfg(feature = "audit")]
    async fn query_events_from_db(&self, pool: &Pool<Postgres>, query: &AuditQuery) -> SecurityResult<Vec<SecurityEvent>> {
        let mut sql = "SELECT * FROM security_events WHERE 1=1".to_string();
        let mut params: Vec<Box<dyn sqlx::Encode<'_, sqlx::Postgres> + Send + Sync>> = Vec::new();
        let mut param_count = 0;

        if let Some(user_id) = &query.user_id {
            param_count += 1;
            sql.push_str(&format!(" AND user_id = ${}", param_count));
            params.push(Box::new(user_id.clone()));
        }

        if let Some(service) = &query.service {
            param_count += 1;
            sql.push_str(&format!(" AND service = ${}", param_count));
            params.push(Box::new(service.clone()));
        }

        if let Some(start_time) = query.start_time {
            param_count += 1;
            sql.push_str(&format!(" AND timestamp >= ${}", param_count));
            params.push(Box::new(start_time));
        }

        if let Some(end_time) = query.end_time {
            param_count += 1;
            sql.push_str(&format!(" AND timestamp <= ${}", param_count));
            params.push(Box::new(end_time));
        }

        sql.push_str(" ORDER BY timestamp DESC");

        if let Some(page_size) = query.page_size {
            param_count += 1;
            sql.push_str(&format!(" LIMIT ${}", param_count));
            params.push(Box::new(page_size as i64));

            if let Some(offset) = query.offset {
                param_count += 1;
                sql.push_str(&format!(" OFFSET ${}", param_count));
                params.push(Box::new(offset as i64));
            }
        }

        // 由于 sqlx 的参数绑定限制，这里使用简化的查询
        let rows = sqlx::query(&sql)
            .fetch_all(pool)
            .await
            .map_err(|e| SecurityError::OperationFailed {
                operation: "query_audit_events".to_string(),
                reason: e.to_string(),
            })?;

        let mut events = Vec::new();
        for row in rows {
            // 解析行数据为 SecurityEvent
            // TODO: 实现完整的行解析逻辑
        }

        Ok(events)
    }
}

impl Default for AuditConfig {
    fn default() -> Self {
        Self {
            enabled: true,
            level: AuditLevel::Detailed,
            storage: AuditStorage::Memory,
            retention_days: 90,
            include_sensitive_data: false,
            batch_size: 100,
            flush_interval: 60,
        }
    }
}

impl Default for SecurityAuditor {
    fn default() -> Self {
        Self::new(AuditConfig::default())
    }
}